using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.IO;
using System.Text;
using System.Reflection;
using System.Runtime.InteropServices;
using System.Windows.Forms;

using Office = Microsoft.Office.Core;
using Outlook = Microsoft.Office.Interop.Outlook;
using System.Drawing;
using System.Globalization;
using Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices;

///
/// Each custom form supports the display of a custom Ribbon at the top of the window
/// when an Outlook item is displayed in its own window.
/// 
/// This object is a factory which support creation and management of Ribbons
/// 
namespace Microsoft.SoftwarePlusServices.ReferenceBits.OutlookPlusServices.Regions
{
    ///
    /// <summary>
    /// The code behind for the ribbon displayed in the custom form region used for items.
    /// </summary>
    ///
    [ComVisible(true)]
    public class RibbonFactory : Microsoft.Office.Core.IRibbonExtensibility
    {
        private List<string> _itemMessageClasses = new List<string>();
        private List<string> _ribbonXMLResourceNames = new List<string>();
        private List<string> _ribbonTags = new List<string>();
        private List<string> _ribbonIDs = new List<string>();
        private List<IRibbonActionInfo> _ribbonActionInfos = new List<IRibbonActionInfo>();


        static System.Resources.ResourceManager _resourceManager = null;

        /// <summary>
        /// Constructor which build a factory utilizing the specified ResourceManager
        /// </summary>
        /// <param name="resourceManager">Resource Manager this object factory should use</param>
        /// 
        ///
        public RibbonFactory(System.Resources.ResourceManager resourceManager)
            : base()
        {
            _resourceManager = resourceManager;
        }

        ///
        /// <summary>
        /// Adds the information which links a Ribbon to a specific type of Outlook item
        /// </summary>
        /// <param name="itemMessageClass">Name of the Outlook item message class supported by this Ribbon</param>
        /// <param name="ribbonTag">Tag used to identify this ribbon for accessing Resources</param>
        /// <param name="ribbonXMLResourceName">Name of the resource containing the XML definition of this Ribbon</param>
        public void AddRibbon(string itemMessageClass, string ribbonID, string ribbonTag, string ribbonXMLResourceName)
        {
            _itemMessageClasses.Add(itemMessageClass);
            _ribbonXMLResourceNames.Add(ribbonXMLResourceName);
            _ribbonTags.Add(ribbonTag);
            _ribbonIDs.Add(ribbonID);
        }

        public void AddRibbonAction(string actionName, string actionArgs, IRibbonAction actionObject)
        {
            _ribbonActionInfos.Add(new IRibbonActionInfo(actionName, actionArgs, actionObject));
        }


        #region Ribbon Display Members

        ///
        /// <summary>
        /// Retreives the ribbon definition for the current ribbon being loaded.
        /// </summary>
        /// <param name="ribbonID">The ID of the ribbon being loaded.</param>
        /// <returns>A string representing the ribbon definition in XML format.</returns>
        ///
        public string GetCustomUI(string RibbonID)
        {
            string retVal;

            if (RibbonID == null)
                throw new ArgumentNullException("RibbonID");
            int i = 0;

            foreach (string _ribbonID in _ribbonIDs)
            {
                if (RibbonID == _ribbonID) //"Microsoft.Outlook.Post.Read"
                {
                    retVal = _resourceManager.GetObject(_ribbonXMLResourceNames[i]) as String;
                    return retVal;
                }
                else
                    i++;
            }

            return string.Empty;
        }

        ///
        /// <summary>
        /// Called by the ribbon to determine if the tab is visible.
        /// </summary>
        /// <param name="ribbonControl">The ribbon control the operation is being performed on.</param>
        /// <returns>A boolean value indicating if the button is visible</returns>
        ///
        public bool GetNonOutlookVisible(Microsoft.Office.Core.IRibbonControl ribbonControl)
        {
            if (ribbonControl == null)
                throw new ArgumentNullException("ribbonControl");

            Outlook.Inspector inspector = (Outlook.Inspector)ribbonControl.Context;
            Outlook.PostItem item = (Outlook.PostItem)inspector.CurrentItem;
            string _tag = ribbonControl.Id;

            foreach (string tag in _ribbonTags)
            {
                if (_tag == tag)
                    return (true);
            }
            return (false);
        }

        ///
        /// <summary>
        /// Called by the ribbon to determine if the outlook tab is visible.
        /// </summary>
        /// <param name="ribbonControl">The ribbon control the operation is being performed on.</param>
        /// <returns>A boolean value indicating if the button is visible</returns>
        ///
        public bool GetOutlookVisible(Microsoft.Office.Core.IRibbonControl ribbonControl)
        {
            if (ribbonControl == null)
                throw new ArgumentNullException("ribbonControl");

            Outlook.Inspector inspector = (Outlook.Inspector)ribbonControl.Context;
            Outlook.PostItem item = (Outlook.PostItem)inspector.CurrentItem;
            string _tag = ribbonControl.Id;

            foreach (string _itemMessageClass in _itemMessageClasses)
            {
                if (item.MessageClass == _itemMessageClass)
                    return (false);
            }

            return (true);

            //foreach(string tag in _ribbonTags)
            //{
            //    if (_tag == tag)
            //        return(false);
            //}
            //return(true);
        }
        #endregion

        #region Ribbon Action Callbacks

        /// <summary>
        /// Handles the actions requested by clicking on the ribbon
        /// The tag of the item defines the method and arguments
        /// </summary>        
        /// <param name="control">The control that initiated the event.</param>
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public void InvokeAction(Microsoft.Office.Core.IRibbonControl control)
        {
            if (control == null)
                throw new ArgumentNullException("control");

            foreach (IRibbonActionInfo info in _ribbonActionInfos)
            {
                if (control.Tag == info.ActionName)
                {
                    info.Action.Execute(control, info.Args);
                }
            }

        }


        ///
        /// <summary>
        /// Called by the ribbon to load the images used in the ribbon.
        /// </summary>
        /// <param name="imageId">The id of the image to load.</param>
        /// <returns>An IPictureDisp interface based on an embedded image.</returns>
        ///
        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Performance", "CA1822:MarkMembersAsStatic")]
        public stdole.IPictureDisp LoadImages(string imageId)
        {
            return GetResourceImage(imageId);
            return null;
        }

        #endregion

        #region Private Methods

        ///
        /// <summary>
        /// Retrieves an image resource and converts it to a IPictureDisp interface.
        /// </summary>
        /// <param name="resourceName">The name of the resource to load.</param>
        /// <returns>An IPictureDisp interface containing the loaded image .</returns>
        ///
        private static stdole.IPictureDisp GetResourceImage(string resourceName)
        {
            Bitmap bitmap =
                _resourceManager.GetObject(resourceName) as Bitmap;
            if (bitmap != null)
                return PictureDispConverter.ToIPictureDisp(bitmap);
            else
                return null;
        }
        #endregion


    }
}
